Skip to content

Issue/datajdbc 557- Insert into table with only id column #1047

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 9 commits into from
Closed

Issue/datajdbc 557- Insert into table with only id column #1047

wants to merge 9 commits into from

Conversation

mipo256
Copy link
Contributor

@mipo256 mipo256 commented Sep 14, 2021

I tried hard and came up with the solution. Please, @schauder @mp911de - can you review this changes. I am very glad to hear your opinions. Thank you in advance :)

Closes #777

@pivotal-cla
Copy link

@mikhail2048 Please sign the Contributor License Agreement!

Click here to manually synchronize the status of this Pull Request.

See the FAQ for frequently asked questions.

@pivotal-cla
Copy link

@mikhail2048 Thank you for signing the Contributor License Agreement!

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Sep 14, 2021
Copy link
Contributor

@schauder schauder left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your work.
This is going in the right direction.
I left a couple of comments for changes we need before we can merge this PR.

Let me know if you need help with these changes.
You'll have to touch the SQL rendering infrastructure, which can be intimidating.
I'm happy to point you in the right direction if necessary.

@@ -37,6 +38,7 @@ public void cycleFree() {
classpath() //
.noJars() //
.including("org.springframework.data.relational.**") //
.excluding("org.springframework.data.relational.core.dialect.**") //
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please do not change this test.
The change also should be superfluous once the .../core/sql no longer references Dialect.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I agree with you, but, when I have applied changes in this PR and supply them with proper tests, this particular test method cause the build to fail. I will try it out again and if I will encounter the same behavior again, I will reach you out.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have still append excluding("org.springframework.data.relational.core.sql.render.**") statement in DependencyTests#cycleFree. The reason is the SqlRenderer is in the org.springframework.data.relational.core.sql.render package, as well as InsertStatementVisitor which I utilize in my case. I mean, we seems to inevitably have to exclude the aforementioned package, have not we? So, I decided to make it so. If I am wrong form your point of view, then, please, feel free to correct me.

@@ -77,4 +81,9 @@ public String toString() {

return builder.toString();
}

@Override
public Dialect getInsertDialect() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dialect should not be used within .../core/sql the point of classes in this package is to represent SQL statements in a dialect independent way.

Instead the SqlRenderer should use the Dialect to generate the dialect dependent SQL.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, that's great, but I think SqlRenderer delegates the creation of SQL INSERT statment to InsertStatementVisitor. I think it will be great to use Dialect in SqlGenerator, because within InsertStatementVisitor we dealing only with an Insert, which (if I understood you correctly, sorry if not) should be dialect-independent - it would be quite complicated to extract Dialect depending logic from their.
I am sorry, I am kind of newbie here :) If I does not grasp something - feel free to correct me.

@mipo256
Copy link
Contributor Author

mipo256 commented Oct 24, 2021

@schauder Please, check out my changes. Please, let me know what you think about this solution)

Copy link
Contributor

@schauder schauder left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The important problems are:

  1. SqlRenderer.render should not take a Dialect as an argument. Instead the necessary information should be part of the SqlRenderer in the first place.

  2. The dependency circle is a no go. But when the rest works I can take care of this.

@@ -675,7 +679,7 @@ private String render(Select select) {
}

private String render(Insert insert) {
return this.sqlRenderer.render(insert);
return this.sqlRenderer.render(insert, dialect);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seem weird. The sqlRenderer already contains information from the Dialect. We should use that route to get the necessary information from the Dialect instead of passing it a second time on the call to render.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, I have removed dialect as parameter and fell back to previous method version. See here

@BeforeEach
public void before() {

DelegatingDataAccessStrategy relationResolver = new DelegatingDataAccessStrategy();
Dialect dialect = HsqlDbDialect.INSTANCE;
dialect = HsqlDbDialect.INSTANCE;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we move the dialect into a field we should also the initialisation with it.
But it would be easier to hard code the exact expected insert statement and leave the Dialect where it is.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved with this


String insert = sqlGenerator.getInsert(emptySet());

assertThat(insert).endsWith("()");
assertThat(insert).endsWith(PostgresDialect.INSTANCE.getSqlInsertWithDefaultValues().getDefaultInsertPart());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, just hard code the expected String. That is much easier to understand.

Also: we should have a second test testing for some other variant of the behaviour using a diiferent dialect.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved here

* @return default implementation of InsertWithDefaultValues
*/
@Override
public InsertWithDefaultValues getSqlInsertWithDefaultValues() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This Default implementation should go in the interface, so it works also for those that don't use the AbstractDialect

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved with this

@@ -69,16 +71,6 @@ public static String toString(Select select) {
return create().render(select);
}

/**
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should still have a way to render an Insert statement without dialect, falling back to sensible defaults.

@mipo256
Copy link
Contributor Author

mipo256 commented Nov 27, 2021

@schauder I have removed dialect from sqlRenderer as a parameter - instead I injected the necessary information into DialectRenderContext, where, I suppose, it should logically be. Also I have resolved the dependency cycle issue. Also I have append ms-sql server unit test for sql generation. Please, check out my changes.

@mipo256 mipo256 requested a review from schauder November 27, 2021 15:58
schauder pushed a commit that referenced this pull request Nov 29, 2021
This broke in the past for some databases that do not support empty value lists.

Closes #777
Original pull request #1047
@schauder
Copy link
Contributor

schauder commented Dec 6, 2021

This was already merged a few days ago. Thanks for your work.

@schauder schauder closed this Dec 6, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: waiting-for-triage An issue we've not yet triaged
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Cannot save entity only have id and collections [DATAJDBC-557]
4 participants